package com.project.im.common.aspect;

import com.alibaba.fastjson.JSON;
import com.project.im.common.annotation.Log;
import com.project.im.common.util.WebUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class LogAspect {

    @Pointcut("@annotation(com.project.im.common.annotation.Log)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object doInterceptor(ProceedingJoinPoint point) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        Exception exception = null;
        Object result = null;
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Method method = methodSignature.getMethod();
        Log logAnno = method.getAnnotation(Log.class);
        String module = logAnno.value();
        try {
            HttpServletRequest request = WebUtils.getRequest();
            Object[] args = point.getArgs();
            String reqParam = "[" + StringUtils.join(args, ", ") + "]";
            log.info("【{}】path: {} params: {}", module, request.getRequestURI(), reqParam);
            stopWatch.start();
            result = point.proceed();
            stopWatch.stop();
        } catch (Exception e) {
            exception = e;
        }
        log.info("【{}】cost: {} ms resp: {}", module, stopWatch.getTotalTimeMillis(), JSON.toJSONString(result));
        if (exception != null) {
            throw exception;
        }
        return result;
    }
}